# withRouter 封装
这里先对自己编写的高阶组件withRouter
做一个汇总,方便查阅:
import { useNavigatge, useParams, useSearchParams } from 'react-router-dom'
function withRouter(WrapperComponent) {
return function (props) {
// 1、路由跳转
const navigate = useNavigatge()
// 2、路径参数
const params = useParams()
// 3、查询参数
const [searchParams] = useSearchParams()
const query = Object.fromEntries(searchParams) // 转换为普通对象
const router = { navigate, params, query }
return <WrapperComponent {...this.props} router={router} />
}
}
export default withRouter
# 1、API 导航
若我们使用的是函数式组件,那我们可以直接使用其提供的 hooks:useNavigatge
useNavigatge 使用示例
- 可传参数
interface NavigateFunction {
(to: To, options?: { replace?: boolean; state?: any }): void
(delta: number): void
}
- 使用示例
import { useNavigatge } from 'react-router-dom'
function Demo(props) {
const navigate = useNavigatge()
function navigateTo(path) {
navigate(path)
}
// 记得要在App.jsx中写上映射关系
return <button onClick={(e) => navigateTo('/category')}>分类</button>
}
那在类组件中,我们该如何操作呢?
答案
既然类组件中无法使用 useNavigatge,那我们自己封装一个高阶组件算了 🤔
核心: 高阶组件 + react-router@5 中的withRouter (opens new window)
- 封装
import { useNavigatge } from 'react-router-dom'
function withRouter(WrapperComponent) {
return function (props) {
const navigate = useNavigatge()
const router = { navigate }
return <WrapperComponent {...this.props} router={router} />
}
}
export default withRouter
- 使用
class Demo extends React.PureComponent {
navigateTo(path) {
// 使用🚩
const { navigate } = this.props.router
navigate(path)
}
render() {
// 记得要在App.jsx中写上映射关系
return <button onClick={(e) => this.navigateTo('/category')}>分类</button>
}
}
export default withRouter(Demo)
# 2、路径参数
若我们使用的是函数式组件,那我们可以直接使用其提供的 hooks:useParams
同样的在类组件中是无法使用的,需要我们封装高阶组件
- 封装
import { useParams } from 'react-router-dom'
function withRouter(WrapperComponent) {
return function (props) {
const params = useParams()
const router = { params }
return <WrapperComponent {...this.props} router={router} />
}
}
export default withRouter
- 使用
class Demo extends React.PureComponent {
navigateToDetails(id) {
// 使用🚩
const { navigate } = this.props.router
navigate('/category/' + id)
}
render() {
return (
<ul>
<li onClick={(e) => this.navigateToDetails(category.id)}>分类</li>
</ul>
)
}
}
export default withRouter(Demo)
class Category extends React.PureComponent {
render() {
const { params } = this.props.router
return (
<div>
<p>id: {params.id}</p>
</div>
)
}
}
export default withRouter(Category)
# 3、查询参数
若我们使用的是函数式组件,那我们可以直接使用其提供的 hooks:useLocation
同样的在类组件中是无法使用的,需要我们封装高阶组件
- 封装
import { useLocation, useSearchParams } from 'react-router-dom'
function withRouter(WrapperComponent) {
return function (props) {
// 方式1
const location = useLocation()
// 方式2
const [searchParams] = useSearchParams()
const query = Object.fromEntries(searchParams) // 转换为普通对象
const router = { location, query }
return <WrapperComponent {...this.props} router={router} />
}
}
export default withRouter
- 使用
class Demo extends React.PureComponent {
navigateToDetails(path) {
// 使用🚩
const { navigate } = this.props.router
navigate(path)
}
render() {
return (
<ul>
<li onClick={(e) => this.navigateToDetails(`/category?id=${category.id}`)}>分类</li>
</ul>
)
}
}
export default withRouter(Demo)
class Category extends React.PureComponent {
render() {
const { location, query } = this.props.router
return (
<div>
<p>id: {location.search}</p>
<p>id: {query.id}</p>
</div>
)
}
}
export default withRouter(Category)
← react路由(上) 基础认知 →